@thallylabs/migrate 0.2.39 → 0.2.41

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -21,6 +21,36 @@ an explicit `scopePath` remains authoritative. Deep article seeds do not widen a
21
21
  mounted documentation tree to its marketing origin. Mintlify configuration page
22
22
  IDs resolve against that mount, while ordinary HTML links keep URL semantics.
23
23
 
24
+ Query strings remain part of page identity. A query URL becomes an article alias
25
+ only after independent captures prove identical article, metadata, deferred source
26
+ and alternative-state content. A section query must name an observed anchor;
27
+ query-selected versions, locales and different articles remain separate pages.
28
+ The alias keeps its own capture evidence and checked section destination.
29
+
30
+ Self-contained inline SVGs become passive, hash-addressed assets. An optional
31
+ trusted `rasterizeSvg` host callback can replace rejected SVG with bounded PNG;
32
+ the engine still checks PNG MIME/signature and records the original SVG digest.
33
+ It never relaxes the SVG allowlist or supplies a browser. Hosts must enforce an
34
+ isolated, credential-free renderer with no network or page JavaScript.
35
+
36
+ Complete ARIA-linked tab panels preserve labels and source order, including
37
+ surrounding authored content. For known embedded article-source contracts, literal
38
+ missing code panels and explicit languages may be recovered only when the source
39
+ is referenced by the article and matches its headings, prose, visible examples
40
+ and tab labels. Embedded imports and expressions never execute. Unreferenced,
41
+ conflicting, incomplete or unsupported alternatives remain review blockers.
42
+
43
+ The Fumadocs adapter reads bounded JSON-only React Flight frames reachable from
44
+ the response's root record. It supports article-owned copy-source references and
45
+ literal `Tabs`/`Tab`/`Accordion` children, including loaded disclosure prose,
46
+ examples, tables and theme-specific images. It renders a fixed set of static
47
+ elements; unknown components, executable markup and unresolved references keep
48
+ their review requirement. Languages come only from explicit source declarations;
49
+ examples without that metadata remain unlabeled. Source heading IDs and known
50
+ Shiki display annotations are recognized for matching while captured code stays
51
+ unchanged. A capture provider can supply complete rendered alternatives when a
52
+ publisher does not expose a supported inert data contract.
53
+
24
54
  The returned `checkpoint` is JSON-safe. `onRecord` lets a host persist a completed
25
55
  page before acknowledging it; `onCheckpoint` emits bounded deltas, including
26
56
  pending discoveries and checkpoint identity fields. Merge delta records by URL,
@@ -42,8 +72,19 @@ Responsive `picture`/`source`/`img` choices retain their descriptors, media
42
72
  conditions, sizing and literal alt text. Every candidate is localized; shared
43
73
  asset URLs are fetched once and identical payloads count once toward the byte
44
74
  budget, including resumed journals. Complete static tab panels are preserved as
45
- alternatives; empty/lazy panels still require a capture provider. Complete local
46
- OpenAPI operations can represent deferred API schemas. Supported native video
75
+ alternatives; empty/lazy panels without verified embedded source still require a capture provider. Complete local
76
+ OpenAPI operations can represent only their exact deferred API fields. A known
77
+ client-rendered request-example contract may use that registered operation to
78
+ regenerate standard language examples; the inline and sidebar slots must be uniquely owned and
79
+ captured panels must be complete. For the supported legacy selected-example
80
+ component, the selected source, title and language must agree with the exact
81
+ root-owned provider inventory. Every authored alternative, including inactive
82
+ same-language examples, is retained byte for byte in the registered specification
83
+ and rendered by the runtime generator. An unmatched or missing inventory remains
84
+ a review blocker. Ordinary language
85
+ pickers and ambiguous or unknown slots still require review. Every captured
86
+ response, including alternative states, receives the same completeness checks;
87
+ the presence of an unrelated state does not excuse a missing panel. Supported native video
47
88
  and YouTube embeds retain their original public media URLs, recorded in source
48
89
  warnings; videos are not downloaded. A trusted host may report an original asset
49
90
  as already absent (HTTP 404/410): its absolute source URL and a warning are
@@ -58,7 +99,7 @@ Missing primary counterparts and projected path collisions require review; the
58
99
  engine does not invent translations. Fresh HTML captures also observe `html lang`; conflicting or unsupported
59
100
  language evidence requires review. Capture adapters can supply `locale` when
60
101
  no language is declared in HTML or identified by the scoped URL path.
61
- The `url-evidence-v5` converter rejects earlier journals: replay retained raw
102
+ The `url-evidence-v6` converter rejects earlier journals: replay retained raw
62
103
  captures into a new journal rather than relabelling previously hashed pages.
63
104
 
64
105
  `stopReason` distinguishes a resumable `capture-limit` from hard `page-limit`
@@ -107,7 +148,8 @@ renderer, so it always produces a clear warning naming the spec instead of
107
148
  disappearing.
108
149
 
109
150
  `METHOD /path` entries (`"POST /v2/keys.createKey"`) under a container that
110
- binds an `openapi` spec become `api.groups` on the tab that spec binds to:
151
+ binds an `openapi` spec become pages of the site (see the next paragraph) or,
152
+ where that is not possible, `api.groups` on the tab that spec binds to:
111
153
  nested groups, icons and authored order are kept, and page entries stay in the
112
154
  tab's own groups (a group that mixes pages and operations is split, so the
113
155
  sidebar lists the API groups after the page groups). Operations written
@@ -137,8 +179,55 @@ site imported by URL, cannot be placed: one warning says they were not added to
137
179
  operations still have their pages. This is separate from a `directory`'s flat
138
180
  operation list, which still only drives the endpoint redirects.
139
181
 
182
+ Mintlify serves one generated page per operation a navigation container lists,
183
+ at `/<directory>/<first tag>/<summary>` (`directory` is the reference's
184
+ `{ source, directory }` folder, `api-reference` when it is a plain string).
185
+ Each such operation becomes an MDX page at that path under `src/content`, so it
186
+ keeps its URL, sidebar entry, eyebrow and previous/next links. Its frontmatter is
187
+ the summary as `title` (else the operation id, else `METHOD /path`), the first
188
+ sentence of the description as `description` (the title when there is none), and
189
+ `openapi: "<spec file> METHOD /path"`; the body is empty. `descriptionPlacement: operation`
190
+ keeps that short summary for search and metadata while the runtime renders the
191
+ full operation description as Markdown, including every paragraph and warning.
192
+ The tab that listed the
193
+ operations is an ordinary page tab, kept where it was among its siblings and
194
+ labelled as they are (`Product: API reference`), whose groups are the authored
195
+ ones, nesting and order kept, each operation replaced by its page. Tabs that were
196
+ separate in the source are never merged, even when they share a spec. The spec
197
+ is bound once per spec file in a hidden tab (`OpenAPI: <spec>`, the same as for a
198
+ spec only a page names), which is what the pages' `openapi:` frontmatter resolves
199
+ against; the renderer serves no `/api/` page, sitemap entry or search record for it. A remote spec's pages
200
+ and tab are made by `hydrateRemoteApiSpecs` once it is downloaded; a download
201
+ that fails leaves no tab and no page, as before. An operation the spec withholds
202
+ (`x-hidden`, `x-excluded`) gets no page, nor does one listed only under a
203
+ `hidden` group or an access-restricted container (such groups are left out of
204
+ the tab, as above). Of two operations with the same tag and
205
+ summary the first listed keeps the URL and one warning names the others; an
206
+ authored page at that URL keeps it. Nothing is redirected from these URLs and a
207
+ link to one stays as written; a link to a tag folder or to an address under the
208
+ directory that matches no page goes to a page, and a folder of pages with no page
209
+ of its own opens on its first page, as in any other navigation. The operations
210
+ fall back to `api.groups` on an API tab, as described above, when the containers
211
+ that share a tab disagree on the directory, the directory cannot be a folder name,
212
+ the spec has none of the listed operations, or the tab is bound to another spec.
213
+ A reference that lists no operation (Mintlify generated every endpoint) is not
214
+ affected. Operations whose path item is a local `$ref` are read as the renderer
215
+ reads them (hidden or excluded on any level of the reference withholds them).
216
+ The renderer tries the first visible API tab's spec first for a bare
217
+ `openapi: "METHOD /path"` page; when converting a tab to pages stops its spec being
218
+ that one, each bare reference to an operation the converted spec defines is
219
+ written with that spec's path in front, so it still renders the same operation.
220
+
140
221
  Mintlify `styling.eyebrows: "breadcrumbs"` becomes `eyebrow: "path"` (the full
141
222
  group path above the page title); `"section"` or no setting writes nothing.
223
+ Mintlify sources also get `smartQuotes: true`, because Mintlify renders straight
224
+ quotes in prose as curly ones; the setting leaves code, heading ids, Markdown and
225
+ `llms.txt` as written.
226
+
227
+ Thally leaves out the sidebar heading of a group named after its tab or dropdown, because
228
+ the collection already names it. Mintlify keeps that heading, so a source with such a group
229
+ (an `API reference` dropdown whose first group is also `API reference`) gets
230
+ `navigation.groupHeadings: "all"`. A source without one gets nothing.
142
231
 
143
232
  Page `openapi:` frontmatter with a spec prefix
144
233
  (`openapi: "specs/openapi-b.yaml GET /widgets/{id}"`) is rewritten to where the
@@ -158,7 +247,8 @@ no operation points to that section's overview page instead, and one warning
158
247
  lists the affected links (up to ten). A link to an address the site answers
159
248
  itself (a guide authored inside an API directory, trailing slash or `/index` or
160
249
  not, or the source of an authored redirect) is never rewritten. A spec that
161
- Mintlify mounted under a `directory` also gets a redirect from each endpoint URL that directory served,
250
+ Mintlify mounted under a `directory` also gets a redirect from each endpoint URL that directory served
251
+ (not the operations a container lists, which are pages at those URLs),
162
252
  to the matching endpoint page, and never to an operation the published spec
163
253
  withholds with `x-hidden` or `x-excluded`. A remote spec gets every directory
164
254
  each of its tabs mounted it under, limited to the operations the navigation
@@ -203,6 +293,15 @@ whose address has a `+ ? ( ) [ ] { }` character (a `directory` such as
203
293
  spec or a downloaded spec is left out instead, and one warning lists the first
204
294
  ten of them.
205
295
 
296
+ A Mintlify page whose frontmatter `url` is a web address is a link in the
297
+ source sidebar. It is imported as a page that is kept out of the sitemap, stays
298
+ in the navigation, and has a redirect from its path to that address. That
299
+ redirect is added after the checks above, because hiding the page is its
300
+ purpose; a `url` that is not an `http(s)` address is ignored. The home page
301
+ (`index.mdx` or `introduction.mdx`) is served at `/` and at `/introduction`, so
302
+ both redirect, and the redirect from `/` replaces the generated one to the first
303
+ page. A redirect for `/` that the source site wrote stays, and a warning says so.
304
+
206
305
  A repository is limited to 5,000 documentation files and, separately, 5,000
207
306
  asset files. Past that, files are kept in navigation order with the default
208
307
  version first, then pages not listed in navigation, and one warning counts and
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { M as MigrationPage, a as MigrationAsset, b as MigrationNavigationGroup, R as RenderedMigrationFile, c as MigrationWarning, d as MigrationFetcher, e as MigrationPlatform, f as MigrationBundle, g as MigrationDocsConfig } from './url-run-BOZvcGs1.js';
2
- export { h as MigrationCapture, i as MigrationCaptureProvider, j as MigrationCaptureState, k as MigrationCapturedAsset, l as MigrationEvidence, m as MigrationFetchRequest, n as MigrationFetchResponse, o as MigrationJournalAsset, p as MigrationNavigationOccurrence, q as MigrationNavigationTab, U as UrlMigrationCheckpoint, r as UrlMigrationCheckpointDelta, s as UrlMigrationIssue, t as UrlMigrationRecord, u as UrlMigrationRun, v as UrlMigrationRunOptions, w as UrlMigrationValidation, x as classifyMigrationResponse, y as mergeMigrationConfig, z as renderMigrationFiles, A as runUrlMigration, B as validateUrlMigration } from './url-run-BOZvcGs1.js';
1
+ import { M as MigrationPage, a as MigrationAsset, b as MigrationNavigationGroup, R as RenderedMigrationFile, c as MigrationWarning, d as MigrationFetcher, e as MigrationPlatform, f as MigrationBundle, g as MigrationDocsConfig, E as EndpointTabSlot } from './url-run-mSKFqHx_.js';
2
+ export { h as MigrationCapture, i as MigrationCaptureProvider, j as MigrationCaptureState, k as MigrationCapturedAsset, l as MigrationEvidence, m as MigrationFetchRequest, n as MigrationFetchResponse, o as MigrationJournalAsset, p as MigrationNavigationOccurrence, q as MigrationNavigationTab, U as UrlMigrationCheckpoint, r as UrlMigrationCheckpointDelta, s as UrlMigrationIssue, t as UrlMigrationRecord, u as UrlMigrationRun, v as UrlMigrationRunOptions, w as UrlMigrationValidation, x as classifyMigrationResponse, y as mergeMigrationConfig, z as renderMigrationFiles, A as runUrlMigration, B as validateUrlMigration } from './url-run-mSKFqHx_.js';
3
3
  export { isPassiveSvg } from './svg-policy.js';
4
4
 
5
5
  /**
@@ -171,6 +171,14 @@ interface MintlifyNavigationResult {
171
171
  referenceAccess: Array<MintlifyReferenceAccess>;
172
172
  /** `sourceRef` mounts under a restricted container; never resolved, so nothing of theirs is imported. */
173
173
  gatedSourceRefs: Array<string>;
174
+ /**
175
+ * The API tabs that list operations and nothing else, which `docsConfig.tabs` leaves out: each with the navigation container that
176
+ * owns it and the place it held among the tabs. Only produced with `operationGroups`; the spec binding puts such a tab back as a page tab.
177
+ */
178
+ apiTabSlots: Array<{
179
+ container: object;
180
+ slot: EndpointTabSlot;
181
+ }>;
174
182
  warnings: Array<MigrationWarning>;
175
183
  }
176
184
  interface MintlifyProjectionOptions {